package com.gy.api.pc.sys.user.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.gy.api.base.Constants;
import com.gy.api.base.RsaKeyProperties;
import com.gy.api.base.Type;
import com.gy.api.pc.sys.authority.dao.SysAuthorityDao;
import com.gy.api.pc.sys.authority.domain.vo.SysAuthoritySearchVO;
import com.gy.api.pc.sys.authority.domain.vo.SysAuthorityVO;
import com.gy.api.pc.sys.role.dao.SysUserRoleDao;
import com.gy.api.pc.sys.role.domain.po.SysUserRolePO;
import com.gy.api.pc.sys.user.dao.SysUserDao;
import com.gy.api.pc.sys.user.domain.po.SysUserPO;
import com.gy.api.pc.sys.user.domain.vo.*;
import com.gy.api.pc.sys.user.service.ISysUserService;
import com.gy.api.tv.domain.vo.SysUserTvOneVO;
import com.gy.api.tv.domain.vo.UserTvLoginVO;
import com.gy.exception.BusinessException;
import com.gy.util.EncryptionUtils;
import com.gy.util.RsaUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.List;


@Service
@Transactional
@Slf4j
public class SysUserServiceImpl implements ISysUserService {


    @Autowired
    private RsaKeyProperties rsaKeyProperties;

    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysUserRoleDao sysUserRoleDao;

    @Override
    public UserLoginResVO login(UserLoginReqVO userLoginReqVO) {
        try{
            PrivateKey privateKey = rsaKeyProperties.getPrivateKey();
            userLoginReqVO.setPassword(RsaUtils.decrypt(userLoginReqVO.getPassword(), privateKey));
            userLoginReqVO.setUsername(RsaUtils.decrypt(userLoginReqVO.getUsername(), privateKey));
        }catch (Exception e){
//            e.printStackTrace();
            throw new BusinessException(Type.FAIL.getCode(),"账号密码错误！请确认");
        }

        Example sysExample = new Example(SysUserPO.class);
        sysExample.and().andEqualTo("loginName",userLoginReqVO.getUsername())
                .andEqualTo("delFlag", Constants.DEL_FLAG_FALSE);
        SysUserPO loginUser=sysUserDao.selectOneByExample(sysExample);
        if(loginUser==null){
            throw new BusinessException(Type.NOT_FOUND_ERROR.getCode(),"登陆用户信息不存在！");
        }
        if(!EncryptionUtils.match(loginUser.getId()+userLoginReqVO.getPassword(),loginUser.getLoginPassword())){
            throw new BusinessException(Type.FAIL.getCode(),"账号密码错误！");
        }
        if(loginUser.getUseState()!=1){
            throw new BusinessException(Type.FAIL.getCode(),"账号已被禁用！");
        }

        StpUtil.login(loginUser.getId(),"pc");
        UserLoginResVO userLoginResVO =new UserLoginResVO();
        userLoginResVO.setId(loginUser.getId());
        userLoginResVO.setToken(StpUtil.getTokenValue());
        userLoginResVO.setIsAdmin(2);
        if(loginUser.getLoginName().equals("admin")){
            userLoginResVO.setIsAdmin(1);
        }
        userLoginResVO.setUserName(loginUser.getUserName());
        return userLoginResVO;
    }


    @Override
    public com.gy.api.mobile.user.domain.vo.UserLoginResVO loginTv(UserTvLoginVO userLoginVO) {
        try{
            PrivateKey privateKey = rsaKeyProperties.getPrivateKey();
            userLoginVO.setPassword(RsaUtils.decrypt(userLoginVO.getPassword(), privateKey));
            userLoginVO.setUsername(RsaUtils.decrypt(userLoginVO.getUsername(), privateKey));
        }catch (Exception e){
//            e.printStackTrace();
            throw new BusinessException(Type.FAIL.getCode(),"账号密码错误！请确认");
        }

        Example sysExample = new Example(SysUserPO.class);
        sysExample.and().andEqualTo("loginName",userLoginVO.getUsername())
                .andEqualTo("delFlag", Constants.DEL_FLAG_FALSE);
        SysUserPO loginUser=sysUserDao.selectOneByExample(sysExample);
        if(loginUser==null){
            throw new BusinessException(Type.NOT_FOUND_ERROR.getCode(),"登陆用户信息不存在！");
        }
        if(!EncryptionUtils.match(loginUser.getId()+userLoginVO.getPassword(),loginUser.getLoginPassword())){
            throw new BusinessException(Type.FAIL.getCode(),"账号密码错误！");
        }
        if(loginUser.getUseState()!=1){
            throw new BusinessException(Type.FAIL.getCode(),"账号已被禁用！");
        }
        StpUtil.login(loginUser.getId(),"pc");
        com.gy.api.mobile.user.domain.vo.UserLoginResVO userLoginResVO = new com.gy.api.mobile.user.domain.vo.UserLoginResVO();
        userLoginResVO.setToken(StpUtil.getTokenValue());
        return userLoginResVO;
    }
    @Autowired
    private SysAuthorityDao sysAuthorityDao;

    @Override
    public SysUserTvOneVO getTvInfo() {
        SysUserTvOneVO retVo=new SysUserTvOneVO();
        SysUserOneVO sysUserOneVO=new SysUserOneVO();
        SysUserPO userPO = sysUserDao.selectByPrimaryKey(StpUtil.getLoginIdAsString());
        if (userPO == null) {
            throw new BusinessException(Type.NOT_FOUND_ERROR.getCode(),  "用户不存在");
        }
        BeanUtils.copyProperties(userPO, sysUserOneVO);

        retVo.setUser(sysUserOneVO);

        Example example=new Example(SysUserRolePO.class);
        example.and().andEqualTo("userId",userPO.getId());
        List<SysUserRolePO> list=sysUserRoleDao.selectByExample(example);
        ArrayList list1=new ArrayList();
        ArrayList list2=new ArrayList();
        for (SysUserRolePO userRolePO:list){
            list1.add(userRolePO.getRoleId());
        }
        retVo.setRoles(list1);
        SysAuthoritySearchVO sysAuthoritySearchVO=new SysAuthoritySearchVO();
        sysAuthoritySearchVO.setUserId(userPO.getId());
        List<SysAuthorityVO> sysAuthorityVOS= sysAuthorityDao.getList(sysAuthoritySearchVO);
        for (SysAuthorityVO authorityVO:sysAuthorityVOS){
            list2.add(authorityVO.getId());
        }
        retVo.setPermissions(list2);
        return retVo;
    }

    @Override
    public List<SysUserVO> getList(SysUserSearchVO searchVO) {
        return sysUserDao.getList(searchVO);
    }


    @Override
    public void resetMyPassword(SysUserMyPasswordVO updateVO) {
        SysUserPO userPO = sysUserDao.selectByPrimaryKey(StpUtil.getLoginIdAsString());
        if (userPO == null) {
            throw new BusinessException(Type.NOT_FOUND_ERROR.getCode(),  "用户不存在");
        }
        try{
            PrivateKey privateKey = rsaKeyProperties.getPrivateKey();
            updateVO.setNewLoginPassword(RsaUtils.decrypt(updateVO.getNewLoginPassword(), privateKey));
            updateVO.setOldLoginPassword(RsaUtils.decrypt(updateVO.getOldLoginPassword(), privateKey));
        }catch (Exception e){
            throw new BusinessException(Type.FAIL.getCode(),"密码参数错误！请确认");
        }
        if(!EncryptionUtils.match(updateVO.getOldLoginPassword(),userPO.getLoginPassword())){
            throw new BusinessException(Type.FAIL.getCode(),"修改失败，旧密码验证不通过！");
        }
        userPO.setLoginPassword(EncryptionUtils.encrypt(userPO.getId()+updateVO.getNewLoginPassword()));
        userPO.preUpdate();
        int i = sysUserDao.updateByPrimaryKeySelective(userPO);
        if (i == Constants.SQL_RETURN_SUCCESS) {
            throw new BusinessException(Type.FAIL);
        }
    }




    @Override
    public SysUserOneVO getOne() {
        SysUserOneVO sysUserOneVO=new SysUserOneVO();
        SysUserPO userPO = sysUserDao.selectByPrimaryKey(StpUtil.getLoginIdAsString());
        if (userPO == null) {
            throw new BusinessException(Type.NOT_FOUND_ERROR.getCode(),  "用户不存在");
        }
        BeanUtils.copyProperties(userPO, sysUserOneVO);
        Example example=new Example(SysUserRolePO.class);
        example.and().andEqualTo("userId",userPO.getId()).andEqualTo("roleId",Constants.EXAMINE_JIA_ROLE);
        sysUserOneVO.setIsExpert(2);
        sysUserOneVO.setIsAdmin(2);
        if(sysUserRoleDao.selectCountByExample(example)>0){
            sysUserOneVO.setIsExpert(1);
        }
        if(userPO.getLoginName().equals("admin")){
            sysUserOneVO.setIsAdmin(1);
        }

        sysUserOneVO.setRoleList(sysUserDao.getUserRole(sysUserOneVO.getId()));
        return sysUserOneVO;
    }


    @Override
    public void add(SysUserAddVO vo) {
        try{
            PrivateKey privateKey = rsaKeyProperties.getPrivateKey();
            vo.setLoginPassword(RsaUtils.decrypt(vo.getLoginPassword(), privateKey));
        }catch (Exception e){
            throw new BusinessException(Type.FAIL.getCode(),"密码参数错误！请确认");
        }
        SysUserPO po = new SysUserPO();
        BeanUtils.copyProperties(vo, po);
        Example example = new Example(SysUserPO.class);
        example.and().andEqualTo("loginName", po.getLoginName()).andEqualTo("delFlag",  Constants.DEL_FLAG_FALSE);
        List<SysUserPO> list = sysUserDao.selectByExample(example);
        if (!list.isEmpty()) {
            throw new BusinessException(Type.EXIST_ERROR.getCode(),  "用户名已存在");
        }
        po.preInsert();
        po.setUseState(1);
        po.setLoginPassword(EncryptionUtils.encrypt(po.getId()+po.getLoginPassword()));
        addUserRole(po, vo.getRoleIds());
        int i = sysUserDao.insertSelective(po);
        if (i == Constants.SQL_RETURN_SUCCESS) {
            throw new BusinessException(Type.FAIL);
        }
    }

    @Override
    public void delete(String id) {
        if (StringUtils.isBlank(id)) {
            throw new BusinessException(Type.PARAM_VALIDATE_FAIL);
        }
        SysUserPO userPO = sysUserDao.selectByPrimaryKey(id);
        if (userPO == null) {
            throw new BusinessException(Type.NOT_FOUND_ERROR.getCode(),  "用户不存在");
        }

        SysUserPO po = new SysUserPO();
        if(userPO.getId().equals(StpUtil.getLoginId())) {
            throw new BusinessException(Type.FAIL.getCode(),"删除失败,当前用户无法删除!");
        }
        if(userPO.getLoginName().equals("admin")) {
            throw new BusinessException(Type.FAIL.getCode(),"超级管理员不能删除");
        }
        po.setId(id);
        po.preDelete();
        int i = sysUserDao.updateByPrimaryKeySelective(po);
        if (i == Constants.SQL_RETURN_SUCCESS) {
            throw new BusinessException(Type.FAIL);
        }
    }

    @Override
    public void disableUser(SysUserStateVO vo) {
        if (StringUtils.isBlank(vo.getId())) {
            throw new BusinessException(Type.PARAM_VALIDATE_FAIL);
        }
        SysUserPO userPO = sysUserDao.selectByPrimaryKey(vo.getId());
        if (userPO == null) {
            throw new BusinessException(Type.NOT_FOUND_ERROR.getCode(),  "用户不存在");
        }
        userPO.setUseState(vo.getUseState());
        userPO.preUpdate();
        int i = sysUserDao.updateByPrimaryKeySelective(userPO);
        if (i == Constants.SQL_RETURN_SUCCESS) {
            throw new BusinessException(Type.FAIL);
        }
    }

    @Override
    public void update(SysUserUpdateVO vo) {
        SysUserPO po = new SysUserPO();
        BeanUtils.copyProperties(vo, po);
        SysUserPO userPO = sysUserDao.selectByPrimaryKey(po.getId());
        if (userPO == null) {
            throw new BusinessException(Type.NOT_FOUND_ERROR.getCode(),  "用户不存在");
        }
        if(StringUtils.isNotEmpty(po.getLoginPassword())){
            try{
                PrivateKey privateKey = rsaKeyProperties.getPrivateKey();
                vo.setLoginPassword(RsaUtils.decrypt(vo.getLoginPassword(), privateKey));
            }catch (Exception e){
                throw new BusinessException(Type.FAIL.getCode(),"密码参数错误！请确认");
            }
            po.setLoginPassword(EncryptionUtils.encrypt(po.getId()+po.getLoginPassword()));
        }

//        if(vo.getRoleIds()!=null&&vo.getRoleIds().size()>0){
//            for (String roleId:vo.getRoleIds()) {
//                SysUserRolePO sysUserRolePO=new SysUserRolePO();
//                sysUserRolePO.setRoleId(roleId);
//                sysUserRolePO.setUserId(po.getId());
//                sysUserRoleDao.insertSelective(sysUserRolePO);
//            }
//        }
        Example example = new Example(SysUserRolePO.class);
        example.and().andEqualTo("userId", po.getId());
        sysUserRoleDao.deleteByExample(example);
        addUserRole(po, vo.getRoleIds());
        po.preUpdate();
        int i = sysUserDao.updateByPrimaryKeySelective(po);
        if (i == Constants.SQL_RETURN_SUCCESS) {
            throw new BusinessException(Type.FAIL);
        }
    }

    /**
     * 添加用户角色
     * @param po
     * @param roleIds
     */
    private void addUserRole(SysUserPO po, List<String> roleIds) {
        if (roleIds != null && roleIds.size() > 0) {
            for (String roleId : roleIds) {
                SysUserRolePO sysUserRolePO = new SysUserRolePO();
                sysUserRolePO.setUserId(po.getId());
                sysUserRolePO.setRoleId(roleId);
                sysUserRoleDao.insertSelective(sysUserRolePO);
            }
        }
    }
    @Override
    public void resetPassword(SysUserPasswordVO updateVO) {
        if (StringUtils.isBlank(updateVO.getId())) {
            throw new BusinessException(Type.PARAM_VALIDATE_FAIL);
        }
        SysUserPO userPO = sysUserDao.selectByPrimaryKey(updateVO.getId());
        if (userPO == null) {
            throw new BusinessException(Type.NOT_FOUND_ERROR.getCode(),  "用户不存在");
        }
        try{
            PrivateKey privateKey = rsaKeyProperties.getPrivateKey();
            updateVO.setLoginPassword(RsaUtils.decrypt(updateVO.getLoginPassword(), privateKey));
        }catch (Exception e){
            throw new BusinessException(Type.FAIL.getCode(),"密码参数错误！请确认");
        }
//        userPO.setLoginPassword(updateVO.getLoginPassword());
        userPO.setLoginPassword(EncryptionUtils.encrypt(userPO.getId()+updateVO.getLoginPassword()));
        userPO.preUpdate();
        int i = sysUserDao.updateByPrimaryKeySelective(userPO);
        if (i == Constants.SQL_RETURN_SUCCESS) {
            throw new BusinessException(Type.FAIL);
        }
    }

    @Override
    public List<SysUserVO> getRole(List<SysUserVO> list) {
        for (SysUserVO vo:list) {
            vo.setRoleList(sysUserDao.getUserRole(vo.getId()));
            if(StringUtils.isBlank(vo.getYkzId())){
                vo.setIsYKZ(2);
            }else{
                vo.setIsYKZ(1);
            }
        }
        return list;
    }

    @Override
    public void deleteBath(List<String> ids) {
        if(ids!=null&&ids.size()>0){
            for (String id:ids){
                this.delete(id);
            }
        }
    }

    @Override
    public List<SysUserOptionVO> getOptionList(SysUserOptionSearchVO searchVO) {
        return null;
    }


}